package com.billdowney.controller.file;

import java.io.OutputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.billdowney.annotation.AuthRoleAllowed;
import com.billdowney.annotation.SystemLogInfo;
import com.billdowney.controller.BaseController;
import com.billdowney.entity.base.BaseEntityPropertyEnum;
import com.billdowney.entity.base.EntityStatus;
import com.billdowney.entity.file.FileInfo;
import com.billdowney.entity.user.UserLoginInfo;
import com.billdowney.service.interfaces.base.SpecParam;
import com.billdowney.service.interfaces.file.FileInfoService;
import com.billdowney.util.CommonUtil;
import com.billdowney.util.auth.AuthRoleConst;
import com.billdowney.util.log.SystemLogHandleType;
import com.billdowney.util.return_type.ReturnData;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * 文件处理控制器
 * 
 * @author 超级小富翁 - BillDowney
 * @data 2017年10月20日 下午11:33:28
 */
@RestController
@RequestMapping(value = "/file")
@Api(tags = "文件处理控制器")
public class FileController extends BaseController {
	@Autowired
	private FileInfoService fileInfoService;

	@AuthRoleAllowed
	@RequestMapping(value = "/fileUpload", method = { RequestMethod.POST })
	@SystemLogInfo(value = "上传文件", handleType = SystemLogHandleType.save)
	@ApiOperation(value = "通用文件上传接口", notes = "文件上传接口，支持多文件上传", response = String.class)
	public Object fileUpload(HttpServletRequest httpServletRequest) throws Exception {
		MultipartHttpServletRequest req = (MultipartHttpServletRequest) httpServletRequest;
		return new ReturnData(fileInfoService.saveAllMultipartFile(req.getFileMap(), false));
	}

	@AuthRoleAllowed
	@RequestMapping(value = "/wangEditorFileUpload", method = { RequestMethod.POST })
	@SystemLogInfo(value = "上传wangEditor中的文件", handleType = SystemLogHandleType.save)
	@ApiOperation(value = "wangEditor插件专用文件上传接口", notes = "wangEditor专用文件上传接口，支持多文件上传")
	public Object wangEditorFileUpload(HttpServletRequest httpServletRequest) throws Exception {
		JSONObject out = new JSONObject();
		out.put("errno", 0);
		MultipartHttpServletRequest req = (MultipartHttpServletRequest) httpServletRequest;
		List<String> fileIds = fileInfoService.saveAllMultipartFile(req.getFileMap(), true);
		JSONArray data = new JSONArray();
		for (String id : fileIds) {
			StringBuffer fileUrl = new StringBuffer();
			// 拼接网络地址
			fileUrl.append(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort());
			// 拼接项目名称
			fileUrl.append(request.getContextPath());
			// 拼接接口地址
			fileUrl.append("/file/" + id);
			data.add(fileUrl.toString());
		}
		out.put("data", data);
		return out;
	}

	@AuthRoleAllowed(AuthRoleConst.NOT_LOGIN)
	@RequestMapping(value = "/{id}", method = { RequestMethod.POST, RequestMethod.GET })
	@SystemLogInfo(value = "文件下载：{visit:requestURI}", handleType = SystemLogHandleType.find)
	@ApiOperation(value = "文件下载", notes = "输入文件id得到一个文件流，如果文件不存在会报10104错误", response = OutputStream.class)
	@ApiImplicitParam(name = "id", value = "文件id", required = true)
	public void fileDownload(@PathVariable(value = "id") String id) throws Exception {
		fileInfoService.fileDownloadById(id, request, response);
	}

	@AuthRoleAllowed(AuthRoleConst.NOT_LOGIN)
	@RequestMapping(value = "/fileDownload", method = { RequestMethod.POST, RequestMethod.GET })
	@SystemLogInfo(value = "文件下载：{id}", handleType = SystemLogHandleType.find)
	@ApiOperation(value = "文件下载", notes = "输入文件id得到一个文件流，如果文件不存在会报10104错误", response = OutputStream.class)
	@ApiImplicitParam(name = "id", value = "文件id", required = true)
	public void fileDownloadById(@RequestParam String id) throws Exception {
		fileInfoService.fileDownloadById(id, request, response);
	}

	@AuthRoleAllowed
	@RequestMapping(value = "/queryFileList", method = { RequestMethod.POST })
	@ApiOperation(value = "查询文件列表", notes = "会根据上传用户来查询列表", response = FileInfo.class)
	@ApiImplicitParams({ @ApiImplicitParam(name = "pageNum", value = "查询页码", defaultValue = "1"),
			@ApiImplicitParam(name = "pageSize", value = "查询数量", defaultValue = "10"),
			@ApiImplicitParam(name = "searchKey", value = "查询key"),
			@ApiImplicitParam(name = "searchValue", value = "查询value") })
	public Object queryFileList(@RequestParam(defaultValue = "1") int pageNum,
			@RequestParam(defaultValue = "10") int pageSize, String searchKey, String searchValue) throws Exception {
		UserLoginInfo userLoginInfo = super.getUserLoginInfo();
		// 组装查询类
		SpecParam param = new SpecParam();
		param.addEqual(BaseEntityPropertyEnum.status.getFieldName(), EntityStatus.using);
		if (CommonUtil.isNotEmpty(userLoginInfo)) {
			param.addEqual("userLoginInfo", userLoginInfo);
		}
		if (CommonUtil.isNotEmpty(searchKey)) {
			param.addLike(searchKey, "%" + searchValue + "%");
		}
		param.addDesc(BaseEntityPropertyEnum.createDate.getFieldName());
		return new ReturnData(fileInfoService.findAll(param, pageNum, pageSize));
	}

	@AuthRoleAllowed
	@RequestMapping(value = "/delFileByIds", method = { RequestMethod.POST })
	@SystemLogInfo(value = "删除文件：{ids}", handleType = SystemLogHandleType.delete)
	@ApiOperation(value = "删除文件", notes = "通过id来删除文件， 此操作会删除物理磁盘数据", response = String.class)
	@ApiImplicitParam(name = "ids", value = "文件id", required = true, allowMultiple = true)
	public Object delFileByIds(@RequestParam String[] ids) throws Exception {
		return new ReturnData("总共：" + ids.length + "条，成功：" + fileInfoService.delFileByIds(ids) + "条");
	}

	@AuthRoleAllowed
	@RequestMapping(value = "/modifyPublicState", method = { RequestMethod.POST })
	@SystemLogInfo(value = "修改公用状态：{ids}", handleType = SystemLogHandleType.update)
	@ApiOperation(value = "修改公用状态", notes = "通过id来修改文件公用状态", response = String.class)
	@ApiImplicitParam(name = "ids", value = "文件id", required = true, allowMultiple = true)
	public Object modifyPublicState(@RequestParam String[] ids) throws Exception {
		return new ReturnData("总共：" + ids.length + "条，成功：" + fileInfoService.modifyPublicState(ids) + "条");
	}

	@AuthRoleAllowed
	@RequestMapping(value = "/modifyFileName", method = { RequestMethod.POST })
	@SystemLogInfo(value = "修改文件名称：{id},{fileName}", handleType = SystemLogHandleType.update)
	@ApiOperation(value = "修改文件名称", notes = "通过id来修改文件名称", response = FileInfo.class)
	@ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "文件id", required = true),
			@ApiImplicitParam(name = "fileName", value = "文件名称", required = true) })
	public Object modifyFileName(@RequestParam String id, @RequestParam String fileName) throws Exception {
		return new ReturnData(fileInfoService.modifyFileName(id, fileName));
	}
}
